//
// Created by Apple on 2021/8/14.
//

#ifndef EXERCIS_CPP_LOGGER_H
#define EXERCIS_CPP_LOGGER_H

#include <string>
#include <memory>
#include "spdlog/spdlog.h"

enum LogLevel
{
    trace = 0,
    debug ,
    info,
    warn,
    err,
    critical,
    off,
    n_levels
};

class Logger {
public:
    Logger();
    ~Logger();

    Logger(const Logger&) = delete;
    Logger(Logger&&) = delete;
    Logger operator=(const Logger&)=delete;
    Logger operator=(Logger&&)=delete;

    void init(std::string logFile, std::size_t fileSzie = 1048576, std::size_t fileCount = 20);
    std::shared_ptr<spdlog::logger> getLogger();
    void setLevel(LogLevel level);
    void setFormat(std::string format);

    static Logger& instance(){
        static Logger instance_;
        return instance_;
    }


private:
    std::shared_ptr<spdlog::logger> logger_;
};

#define LOG_LOGGER_CALL(logger, level, ...) (logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)

#define LOG_LOGGER_TRACE(logger, ...) LOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)
#define LOG_TRACE(...) LOG_LOGGER_TRACE(Logger::instance().getLogger(), __VA_ARGS__)

#define LOG_LOGGER_DEBUG(logger, ...) LOG_LOGGER_CALL(logger, spdlog::level::debug, __VA_ARGS__)
#define LOG_DEBUG(...) LOG_LOGGER_DEBUG(Logger::instance().getLogger(), __VA_ARGS__)

#define LOG_LOGGER_INFO(logger, ...) LOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__)
#define LOG_INFO(...) LOG_LOGGER_INFO(Logger::instance().getLogger(), __VA_ARGS__)

#define LOG_LOGGER_WARN(logger, ...) LOG_LOGGER_CALL(logger, spdlog::level::warn, __VA_ARGS__)
#define LOG_WARN(...) LOG_LOGGER_WARN(Logger::instance().getLogger(), __VA_ARGS__)

#define LOG_LOGGER_ERROR(logger, ...) LOG_LOGGER_CALL(logger, spdlog::level::err, __VA_ARGS__)
#define LOG_ERROR(...) LOG_LOGGER_ERROR(Logger::instance().getLogger(), __VA_ARGS__)

#define LOG_LOGGER_CRITICAL(logger, ...) LOG_LOGGER_CALL(logger, spdlog::level::critical, __VA_ARGS__)
#define LOG_CRITICAL(...) LOG_LOGGER_CRITICAL(Logger::instance().getLogger(), __VA_ARGS__)




//#define LDebug(...)  SimLog::Instance().GetLogger()->debug(__VA_ARGS__)
//#define LInfo(...)  SimLog::Instance().GetLogger()->info(__VA_ARGS__)
//#define LWarn(...) SimLog::Instance().GetLogger()->warn(__VA_ARGS__)
//#define LError(msg,...)  SimLog::Instance().GetLogger()->error(SUFFIX(msg),__VA_ARGS__)
//#define LCritical(...)  SimLog::Instance().GetLogger()->critical(__VA_ARGS__)


#endif //EXERCIS_CPP_LOGGER_H
